#include <iostream>
#include <string.h>
#include <gflags/gflags.h>
#include <signal.h>
#include <unistd.h>
using namespace std;
using namespace google;
#define ngx_signal_helper(n)     SIG##n
#define ngx_signal_value(n)      ngx_signal_helper(n)
#define ngx_value_helper(n)   #n
#define ngx_value(n)          ngx_value_helper(n)
#define NGX_SHUTDOWN_SIGNAL      QUIT
#define NGX_TERMINATE_SIGNAL     TERM
#define NGX_NOACCEPT_SIGNAL      WINCH
#define NGX_RECONFIGURE_SIGNAL   HUP
#define NGX_REOPEN_SIGNAL        USR1
#define NGX_CHANGEBIN_SIGNAL     USR2
#define ngx_errno                  errno
#define NGX_OK					0
#define NGX_ERROR				-1
typedef intptr_t ngx_int_t;
typedef int ngx_err_t;
static void
ngx_signal_handler(int signo, siginfo_t *siginfo, void *ucontext);
typedef struct {
	int     signo;
	char   *signame;
	char   *name;
	void(*handler)(int signo, siginfo_t *siginfo, void *ucontext);
} ngx_signal_t;
ngx_signal_t  signals[] = {
	{ ngx_signal_value(NGX_RECONFIGURE_SIGNAL),
	"SIG" ngx_value(NGX_RECONFIGURE_SIGNAL),
	"reload",
	ngx_signal_handler },

	{ ngx_signal_value(NGX_REOPEN_SIGNAL),
	"SIG" ngx_value(NGX_REOPEN_SIGNAL),
	"reopen",
	ngx_signal_handler },

	{ ngx_signal_value(NGX_NOACCEPT_SIGNAL),
	"SIG" ngx_value(NGX_NOACCEPT_SIGNAL),
	"",
	ngx_signal_handler },

	{ ngx_signal_value(NGX_TERMINATE_SIGNAL),
	"SIG" ngx_value(NGX_TERMINATE_SIGNAL),
	"stop",
	ngx_signal_handler },

	{ ngx_signal_value(NGX_SHUTDOWN_SIGNAL),
	"SIG" ngx_value(NGX_SHUTDOWN_SIGNAL),
	"quit",
	ngx_signal_handler },

	{ ngx_signal_value(NGX_CHANGEBIN_SIGNAL),
	"SIG" ngx_value(NGX_CHANGEBIN_SIGNAL),
	"",
	ngx_signal_handler },

	{ SIGALRM, "SIGALRM", "", ngx_signal_handler },

	{ SIGINT, "SIGINT", "", ngx_signal_handler },

	{ SIGIO, "SIGIO", "", ngx_signal_handler },

	{ SIGCHLD, "SIGCHLD", "", ngx_signal_handler },

	{ SIGSYS, "SIGSYS, SIG_IGN", "", NULL },

	{ SIGPIPE, "SIGPIPE, SIG_IGN", "", NULL },

	{ 0, NULL, "", NULL }
};

static bool ValidatePort(const char *flagname, int32_t val)
{
	if (val > 0 && val < 32768)
		return true;
	return false;
}
DEFINE_string(s, "", "reload pragam");
DEFINE_int32(pid, 0, "process id");
ngx_int_t
ngx_init_signals();
static bool brun = true;
int main(int argc, char **argv)
{
	ParseCommandLineFlags(&argc, &argv, true);	
	if (FLAGS_s.compare("reload") == 0)
	{
		kill(FLAGS_pid, ngx_signal_value(NGX_RECONFIGURE_SIGNAL));
	}
	else{
		ngx_init_signals();
		do 
		{
			sleep(1);
		} while (brun);
		
	}		
	return 0;
}


ngx_int_t
ngx_init_signals()
{
	ngx_signal_t      *sig;
	struct sigaction   sa;

	for (sig = signals; sig->signo != 0; sig++) {
		memset(&sa,0, sizeof(struct sigaction));

		if (sig->handler) {
			sa.sa_sigaction = sig->handler;
			sa.sa_flags = SA_SIGINFO;

		}
		else {
			sa.sa_handler = SIG_IGN;
		}

		sigemptyset(&sa.sa_mask);
		if (sigaction(sig->signo, &sa, NULL) == -1) {
			return NGX_ERROR;
		}
	}

	return NGX_OK;
}
static void
ngx_signal_handler(int signo, siginfo_t *siginfo, void *ucontext)
{
	char            *action;
	ngx_int_t        ignore;
	ngx_err_t        err;
	ngx_signal_t    *sig;

	ignore = 0;

	err = ngx_errno;

	for (sig = signals; sig->signo != 0; sig++) {
		if (sig->signo == signo) {
			break;
		}
	}


	action = "";

	switch (signo) {

	case ngx_signal_value(NGX_SHUTDOWN_SIGNAL):		
		break;

	case ngx_signal_value(NGX_TERMINATE_SIGNAL):
	case SIGINT:		
		break;

	case ngx_signal_value(NGX_NOACCEPT_SIGNAL):		
		break;

	case ngx_signal_value(NGX_RECONFIGURE_SIGNAL):
		printf("rev signal hup\n");
		brun = false;
		break;

	case ngx_signal_value(NGX_REOPEN_SIGNAL):		
		break;

	case ngx_signal_value(NGX_CHANGEBIN_SIGNAL):		
		break;

	case SIGALRM:		
		break;

	case SIGIO:		
		break;

	case SIGCHLD:		
		break;
	}	
}
